<?php

	fta_registerModules(
		array(
		"FTACart/FTACart"
		)
	);

	class MAICart extends FTACart {
		

		function __construct() {
			parent::__construct();			
			

		}
		
		function addItemToOrder(){
			$this->orderContainer->log($this->orderContainer->id() . " adding items to cart");
			
			$this->lastKnownCartPhase = ORDER_ITEM;//tis will get overwritten with ORDER_DISPLAY
			
			$this->orderContainer->takeValueForKey($this->getCurrency(),'currency');
			$this->orderContainer->takeValueForKey($this->getCurrencySign(),'currencySign');
					
			# this creates and adds an order item to the shopping cart...
			
			#1. create it..
				global $CMS_ORDERITEM_CLASS;
				$orderItem = new $CMS_ORDERITEM_CLASS();

			#2. add it to the order container.
				$this->orderContainer->takeValueForKey($orderItem->valueForKey('id'), 'currentOrderItemId');
				$this->orderContainer->setOrderItemWithId($orderItem->valueForKey('id'), $orderItem);
				
				#echo "order container = <pre>";print_r($this->orderContainer);echo "</pre>";
				
			#3. let the order item know who its order container is..
				$orderItem->takeValueForKey($this->orderContainer->valueForKey('id'), "orderContainer" );
				$this->orderContainer->log($this->orderContainer->id() . " has order item: " . $orderItem->id());
				
				/*
				 map the passed in keys to the object..
				 we do this by altering the request variables
				 and calling takeValuesFromRequest.
				*/
			
			#4. get the list of keys that this object expects to read in from the request.
				$initalKeys = $this->getAddItemRequiredKeys();// <----- 
				//$initalKeys = $orderItem->keys();//flatten the keys out into one array....
				
				$containerKeys = $this->orderContainer->keys;
				foreach ($containerKeys as $key => $value) {
					foreach ($containerKeys[$key] as $key2 => $value2) {
						$initalKeys[] = $value2;
					}
				}
				#echo "keys = <pre>";print_r($initialKeys);echo "</pre><br>";
				
			#5. rename the fields so that they can be picked up by takeValuesFromRequest.	
				$id= $orderItem->valueForKey('id');
				foreach ($initalKeys as $key) {
					if (key_exists($key,$_REQUEST)&& !is_null($_REQUEST[$key])){
						$_REQUEST[$id . '_' .$key] = $_REQUEST[$key];
					}
				}
				
			#	FOR FORMMAILERDATA
				global $_POST;
				if(isset($_POST['formMailerDataForOrderItem']) ){
					$_POST[$id . '_' . 'formMailerDataForOrderItem'] = $_POST['formMailerDataForOrderItem'];
				}
				
				# 	NEED TO SAVE FORM DATA TO ORDERITEM IF WE HAVE SOME
				
				if(isset($_POST['formMailerDataForOrderItem']) ){
			 		$formDataForCart[$_POST['formMailerId']][$id] = unserialize($_POST['formMailerDataForOrderItem']);
			 		//$_SESSION['formDataForCart'] = $formDataForCart;
			 		
			 		#	NEED TO SAVE TO ORDERITEM
					$orderItem->takeValueForKey($_POST['formMailerDataForOrderItem'],'formMailerDataForOrderItem');
					$formDataDisplay = '';
					foreach ($formDataForCart[$_POST['formMailerId']][$id] as $key=>$value ) {
						$formDataDisplay .= "<strong>" . $key. "</strong> - " . $value . "<br />";
					}
					
					
					$orderItem->takeValueForKey($formDataDisplay, 'formData');
					//$orderItem->takeValueForKey(print_r($formDataForCart[$_POST['formMailerId']][$id], true), 'formData');
					$orderItem->takeValueForKey($_POST['formMailerId'], 'formMailerId');
					$orderItem->takeValueForKey($_POST['member'], "member");
					//echo "member = <pre>";print_r($orderItem->valueForKey('member'));echo "</pre><br />";
					
			 	}
				
			#6. populate fields. and what not..
				# $orderItem->takeValuesFromRequest();
				# pruge empty items here.. just in case
				$this->orderContainer->takeValuesFromRequest();
				$this->orderContainer->purgeEmptyOrderItems();
				
				
			
				
			#7.. we can possibly now fall through to the view cart page.
			# or possibly an order item details page .. TBA

				$this->displayOrder();
		}
		
		function submitOrder(){
			
			//these need to be factored into methods for easy replacement.
			$this->lastKnownCartPhase = ORDER_SUBMIT;
			$this->orderContainer->log($this->orderContainer->id() . " Performing Order Submit");
			
			global $db;
			//global $CMS_ORDERCONTAINER_CLASS;
			
			
			$this->orderContainer->takeValueForKey($this->getCurrency(),'currency');	
		
					
			$valid = false;
			$valid = $this->orderContainer->validateForSave();

			if (!$valid) {
				
				$this->orderContainer->log($this->orderContainer->id() . " Order not valid, going back to cart..");
				
				$_SESSION["FTACart"] = &$this;
				
				while (@ob_end_clean());
				header("Location: " . $this->getCartUrl() ,true);
				die();
				
			} else {
				
	
				# if we are here VVVVV data is valid and we have submitted the form/cart ready for payment..
				$this->orderContainer->log($this->orderContainer->id() . " Preparing DPS payload");
				
				$this->orderContainer->takeValueForKey( ORDER_STATUS_PENDING, 'status');
				
				$request = new PxPayRequest();	

//				if($this->orderContainer->valueForKey('country') == 140) {
//fetcht this onces as it needs a trawl of the order items..
				$totalPrice = $this->orderContainer->valueForKey('totalPrice');
				$this->orderContainer->log($this->orderContainer->id() . " Setting transaction amount: " . $totalPrice );
				$request->setAmountInput( $this->orderContainer->valueForKey('totalPrice') ) ;
//				} else {
//					$request->setAmountInput( $this->orderContainer->internationalTotalPrice() ) ;
//				}
				

		  		$request->setTxnData1(  $this->getTransactionMessage() );# whatever you want to appear
				# $request->setTxnData2( 'DPS AUTH' );# whatever you want to appear
				# $request->setTxnData3("data three");# whatever you want to appear
				
				$this->orderContainer->log($this->orderContainer->id() . " Setting transaction Type: " . $this->getTransactionMessage() );
		  		$request->setTxnType($this->getTransactionType());
				
		  		#set the currency..
		  		$this->setCurrency( (strlen($this->getCurrency()) == 3) ? $this->getCurrency() : "NZD");
				$this->orderContainer->log($this->orderContainer->id() . " Setting currency Type: " . $this->getCurrency() );
		  		
				$request->setCurrencyInput($this->getCurrency());
//				$request->setInputCurrency($this->getCurrency());
		  		
		  		$request->setEnableAddBillCard(1);
		  		$request->setBillingId($this->orderContainer->valueForKey('firstName') . " " . $this->orderContainer->valueForKey('lastName'));
		  		
		  		$request->setMerchantReference($this->orderContainer->valueForKey('id')); # fill this with your order number
		  		$request->setEmailAddress($this->orderContainer->valueForKey('email'));
				
		  		# set the return urls etc.... this will just be php_self really.. i hope so..		  		
				$request->setUrlFail( PAYMENT_SUCCESS_URL );
		  		$request->setUrlSuccess( PAYMENT_FAIL_URL );			  		

		  		$request->setTxnId($this->orderContainer->id());
		  		
		  		$pxaccess = $this->getPxAccess();
		  		$requestString = $pxaccess->makeRequest($request);
				$this->orderContainer->log($this->orderContainer->id() . " DPS Request: " . print_r($request,true) );
		  		$pxaccess = null;		  		
	  		
		  		$pxXml = $request->toXml();
		  		$this->orderContainer->takeValueForKey( $pxXml, 'pxSend');

				
				$response = new MifMessage($requestString);
					
  				$dpsUrl = $response->get_element_text("URI");
  				$valid = $response->get_attribute("valid");
  				
				if ($valid) {
					$this->orderContainer->log($this->orderContainer->id() . " DPS request response valid, presisting changes" );	
				
		  			$this->orderContainer->takeValueForKey( "Now", 'transactionDate');
	 				$authInfo = setupPublicUser();
					$ut = $authInfo->usertype;
					$authInfo->usertype = 0;
								
				} else {
					$this->orderContainer->log($this->orderContainer->id() . " DPS request response not valid" );
				}

//				
		  		$res = $this->orderContainer->save( $authInfo, $db );
				$authInfo->usertype = $ut;

				if (!$valid || $res->hasErrors) {
					/*
					 display an error message here.. and die..
					 every thing should be valid.. and saved properly.
					 echo "ERROR WITH SAVE FOR SOME REASON..";
					 myPrintR($res);
					
					 we need to set up state and then redirect to a point where we
					 display the error screen in the final step.
					*/
					$_SESSION["FTACart"] = &$this;
					$this->orderContainer->log($this->orderContainer->id()." Failed to save to DB.");
					// include( CMS_ORDER_FINALISE_PAGE );//make a define for this..
					
					while (@ob_end_clean());
					header("Location: " . $this->getConfirmUrl() ,true);					
					die();
					
				} else {
					//dont actually care at this point in time..
					$_SESSION["FTACart"] = &$this;
					
					//$this->orderContainer->log($this->orderContainer->id()." ".$this->orderContainer->toXml());
					$this->orderContainer->log($this->orderContainer->id()." DPS XML: ".$request->toXml());
					$this->orderContainer->log($this->orderContainer->id()." Going to DPS.. Total Order: '". $this->orderContainer->valueForKey('totalPrice') ."'.");
					
					# NEED TO SAVE THE FORMS IF WE HAVE ANY
					
					
					require_once("fta.201003310000/fta.php");
					fta_registerModules(
						array(
						"FTAFormMailer/ftaFormMailer"
					));
					
					global $db;
					$authInfo = setupPublicUser();
					$recipients = array();
					
					//loop over it and save the forms
					if($this->orderContainer->valueForKey("formsent") == ''){
						foreach ($this->orderContainer->orderItems() as $oi){
						
							if(strlen($oi->valueForKey('formMailerDataForOrderItem')) > 0 && strlen($oi->valueForKey('formMailerId')) > 0){	
							
								$formId = $oi->valueForKey('formMailerId');
								$formDescriptor = fta_getFormMailerFormDescriptor($formId,$db);
							
								//loop over each form and save
								$formData = unserialize($oi->valueForKey('formMailerDataForOrderItem'));
							
								$invalidFields = array();
							
								$formData['orderItemId'] = $oi->valueForKey('id');//echo "Item Id = <pre>";print_r($itemId);echo "</pre><br /><br />";
								$formData['containerId'] = $this->orderContainer->id();//echo "container Id = <pre>";print_r($this->orderContainer->id);echo "</pre><br /><br />";
							
								$formSent = fta_formMailerSendForm($formDescriptor,$formData,$recipients, $authInfo, $invalidFields, $db );
								//echo "formSent = <pre>";print_r($formSent);echo "</pre><br /><br />";
								//echo "invalidFields = <pre>";print_r($invalidFields);echo "</pre><br /><br />";
								//echo "Form Data = <pre>";print_r($formData);echo "</pre><br /><br />";
							
							}
						
						
						}
						$this->orderContainer->takeValueForKey( "true", 'formsent');
						$ut = $authInfo->usertype;
						$authInfo->usertype = 0;
						
						$res = $this->orderContainer->save( $authInfo, $db );
						$authInfo->usertype = $ut;
						$_SESSION["FTACart"] = &$this;
					
					}
					
					$authInfo->usertype = $ut;
					//die();exit();
						
						
					
					
					while (@ob_end_clean());  
					header("Location: $dpsUrl",true);
					die();
				}
			}				
		}
		
		function finaliseOrder(){
			 
			$this->lastKnownCartPhase = ORDER_FINALISE;

			$this->orderContainer->log($this->orderContainer->id() . " Entering Order Finalise:");
			
			global $db;
			
			/*
			 do the ecommerce bit..
			 record the order
			 and process ecommerce results??
			 now we may need to look up the session here.. to finalise things.. as this will also be triggered by
			 the dps..
			*/
			$dpsSuccess = 0;
			$dpsAuthCode = null;
			$dpsMessage = null;
			
			$dpsResult = extractStringWithKeyFromArray('result', $_REQUEST, null);
			
			$pxaccess = $this->getPxAccess();	
			$pxResponse = $pxaccess->getResponse( $dpsResult );
				
			if(!is_null($pxResponse) && $pxResponse->getMerchantReference()){
				$dpsSuccess = $pxResponse->getSuccess();
				$dpsAuthCode = $pxResponse->getAuthCode();
				$dpsMessage = 'DPS '.$pxResponse->getResponseText();
				$pxXml = $pxResponse->toXml();	
			}

			//kvc operation?
			$status = $this->orderContainer->status();
			
			$sendInvoice=false;
			if ($status == ORDER_STATUS_PENDING  ) {

				$this->orderContainer->log($this->orderContainer->id() . " Finalising Pending Order");
				
				$this->orderContainer->takeValueForKey( $dpsMessage, 'responseText' );
		  		$this->orderContainer->takeValueForKey( $pxXml, 'pxReceive');
				$this->orderContainer->takeValueForKey( $dpsAuthCode, 'authCode');
			  		
				if ($dpsSuccess == 1)  {
					
					$this->orderContainer->log($this->orderContainer->id() . " DPS success.");
					//$this->orderContainer->takeValueForKey( ORDER_STATUS_AUTH, 'status');
					//This needs to swap depending on the type of transaction
					if($this->getTransactionType() == "Purchase") {
						$this->orderContainer->log($this->orderContainer->id() . " Status set to: " . ORDER_STATUS_ACCEPTED);
						$this->orderContainer->takeValueForKey( ORDER_STATUS_ACCEPTED, 'status');
					} else {
						$this->orderContainer->log($this->orderContainer->id() . " Status set to: " . ORDER_STATUS_AUTH);
						$this->orderContainer->takeValueForKey( ORDER_STATUS_AUTH, 'status');
					}
					
					$sendInvoice=true;
					
					$this->orderContainer->log($this->orderContainer->id() . " Running finalise Process");
					global $FTACartFinaliseProcess;					
					include_once((0 < strlen($FTACartFinaliseProcess)) ? $FTACartFinaliseProcess : "ftaCartFinaliseProcess.php");

					$this->lastKnownCartPhase = ORDER_FINALISE_SUCCESS;
					
					# ON SUCESS WE UPDATE THE SPACES LEFT ON A CLASS
					//  1.  Loop through order items and determine if there is a class product.
					global $db;	
					$cmsDocument = new CmsDocument($db);
					foreach ($this->orderContainer->orderItems() as $oi) {
						$pid = $oi->valueForKey('productId');
						//open product
						$product = $cmsDocument->openDocument($pid);
						if($product->documenttypecode == 'docClasses'){
							//  2.  If there is a class get the no of spaces for the class and reduce by one and re-save
							//authordepartment = spaces
							
							$fileDataToSave = array();
							$fileDataToSave['documenttypecode'] = 'docClasses';
							$fileDataToSave['documentcode'] = $pid;
							$fileDataToSave['listlabel'] = $product->listlabel;
							$fileDataToSave['title'] = $product->title;
							$fileDataToSave['shortdescription'] = $product->shortdescription;
							$fileDataToSave['startdate'] = $product->startdate;
							$fileDataToSave['enddate'] = $product->enddate;
							$fileDataToSave['authordepartment'] = ($product->authordepartment - 1);
							$fileDataToSave['url'] = $product->url;
							$fileDataToSave['extra1'] = $product->extra1;
							//$fileDataToSave['extra11'] = $product->extra11;
							$fileDataToSave['extra13'] = $product->extra13;
							$fileDataToSave['extra14'] = $product->extra14;
							$fileDataToSave['extra15'] = $product->extra15;
                                                        $fileDataToSave['rank_cmsmetadata'] = $product->rank;
							
							$authInfo = setupPublicUser();
							$ut = $authInfo->usertype;
							$authInfo->usertype = 0;
							
							$cmsWriter = new CmsWriter(1028, $pid, $fileDataToSave, $authInfo, $db);	
							
							$message = $cmsWriter->processFormData();	
							//echo "Message = <pre>";print_r($message);echo "</pre><br /><br />";				
												
							$authInfo->usertype = $ut;
						}
						
					}
					
					
					
					
					
					
				} else {
					$this->orderContainer->log($this->orderContainer->id() . " DPS declined.");					
					$this->orderContainer->takeValueForKey( ORDER_STATUS_DECLINED, 'status');
					
					$this->lastKnownCartPhase = ORDER_FINALISE_FAIL;
					
				}
										
				$authInfo = setupPublicUser();
				$ut = $authInfo->usertype;
				$authInfo->usertype = 0;
		  		$res = $this->orderContainer->save( $authInfo, $db );
				$authInfo->usertype = $ut;
											
											
			} else {
				$this->orderContainer->log($this->orderContainer->id() . " Order status already updated to: " . $status);
				
			}
			
			$this->orderContainer->log($this->orderContainer->id() . " Displaying Finalise Page"); 
			if ($dpsSuccess == 1) {
				$this->lastKnownCartPhase = ORDER_FINALISE_SUCCESS;							
			} else {
				$this->lastKnownCartPhase = ORDER_FINALISE_FAIL;							
			}
			
			# this page is the page that is displayed .. it is always shown.. and just reflects the order status.
			//include( CMS_ORDER_FINALISE_PAGE );
						
			global $FTACartFinalisePage;						
			include_once((0 < strlen($FTACartFinalisePage)) ? $FTACartFinalisePage : "ftaCartFinalise.php");					
			mai_cartCleanup();
			
			
		}
		
		function cancelOrder() {
			
			global $db;

			$this->orderContainer->log($this->orderContainer->id() . " order cancelled" );

			$authInfo = setupPublicUser();
			
			$this->lastKnownCartPhase = ORDER_CANCEL;// we should take this from order step.. but it may not be defined..
			/*
			 cancel the order.. at some point in the future we may want to 
			 add more advanced cleanup  code.. dumping the session for now is 
			 fine..
			*/

			$authInfo = setupPublicUser();
			$ut = $authInfo->usertype;
			$authInfo->usertype = 0;
			$this->orderContainer->cancelOrder($authInfo, $db);
			$authInfo->usertype = $ut;
							

			// $_SESSION["FTACart"] = &$this;
			$_SESSION["MAICart"]->orderContainer->orderItems = array();
			
			
			//
			while (@ob_end_clean());
									
			header("Location: " . $this->getShopUrl() ,true);
			die();					
		}
	}
	
	
	function mai_getCart(){
		ob_start();
		$maiCart = mai_getSharedCartObject();
		$maiCart->renderCart();	
		return ob_get_clean();
	}
	
	function mai_getSharedCartObject(){
		
		global $FTACartClass;
				
		//FIXME: cant have side effects on the global variable.
		//this is a simple registration hook to ensure that the correct subclass files are loaded
		//before sessions
		global $FTACartClass;
		if(!is_null($FTACartClass)){
		} else {
			$FTACartClass = "MAICart";
		}
		
		if(!isset($_SESSION)) {
			session_start();
		}
		
		$o = extractObjectWithKeyOfClassFromArray('MAICart',$FTACartClass,$_SESSION,null );
		if (is_null($o)){		
			$o = new $FTACartClass();			
		}
		
		//we need to remember to stick things back in the session if we fuck about with them
		$_SESSION['MAICart'] = $o;	
				
		return $o;	
		
		
	}
	
	function mai_cartCleanup(){
		// we work out the last known step and clen up.. this should always be the last item to run in a cart page..
		// we dont dont this in the object.. as its bad.. and will get confusing..
		$ftaCart = mai_getSharedCartObject();
		if (ORDER_FINALISE_SUCCESS == $ftaCart->lastKnownCartPhase ) {
			//successful orders can goes here.. 
			// here we just remove all of the objects.. and hope that they go away..
			$ftaCart = null;
			unset($_SESSION['MAICart']);
			
			
			//
		} else if (ORDER_FINALISE_FAIL == $ftaCart->lastKnownCartPhase ) {
			//fail orders here.  // not sure if we need to clean up or not .. just leave for now.. 
			//Must clean up as the orders are getting stuck!!!
			$ftaCart = null;
			unset($_SESSION['MAICart']);
		} else {
			//the rest of the states.. 	//nothing happens here.. 
		}
		
	}
?>
